// 高阶组件（HOC）是React中用于复用组件逻辑的一种高级技巧。
// HOC自身不是React一部分，它是基于React的组合特性而形成的设计模式。

// 具体而言，高阶组件是参数为组件，返回值为新组件的函数。

// const EnhancedComponent = higherOrderComponent(WrappedComponent)

// 组件是将props转化为UI，而高阶组件是将组件转化为另一个组件。

// HOC在React的第三方库中很常见，例如Redux的connect()。

// 在本文档中，我们将讨论为什么高阶组件有用，以及如何编写自己的HOC函数。


// 使用HOC解决横切关注点问题。


import React from 'react';
import DataSource from '../utils/index'


function Comment(props) {
    console.log('props',props)
    return(
        <li>{props.comment.text}</li>
    )
}

class CommentList extends React.Component {
    constructor(props) {
      super(props);
      this.handleChange = this.handleChange.bind(this);
      this.state = {
        // 假设 "DataSource" 是个全局范围内的数据源变量
        comments: DataSource.getComments()
      };
    }
  
    componentDidMount() {
      // 订阅更改
      DataSource.addChangeListener(this.handleChange);
    }
  
    componentWillUnmount() {
      // 清除订阅
      DataSource.removeChangeListener(this.handleChange);
    }
  
    handleChange() {
      // 当数据源更新时，更新组件状态
      this.setState({
        comments: DataSource.getComments()
      });
    }
  
    render() {
        console.log('this.state.comments',this.state.comments)
        return (
            <ul>
                {
                    this.state.comments.map((comment) => (
                        <Comment comment={comment} key={comment.id} />
                    ))
                }
            </ul>
        );
    }
}


function TextBlock(props) {
    return <div>{props.text}</div>
}

class BlogPost extends React.Component {
    constructor(props) {
      super(props);
      this.handleChange = this.handleChange.bind(this);
      this.state = {
        blogPost: DataSource.getBlogPost(props.id)
      };
    }
  
    componentDidMount() {
      DataSource.addChangeListener(this.handleChange);
    }
  
    componentWillUnmount() {
      DataSource.removeChangeListener(this.handleChange);
    }
  
    handleChange() {
      this.setState({
        blogPost: DataSource.getBlogPost(this.props.id)
      });
    }
  
    render() {
      return <TextBlock text={this.state.blogPost} />;
    }
}


function withSubscription(WrappedComponent,selectData) {
    return class extends React.Component {
        constructor(props) {
            super(props)
            this.handleChange =  this.handleChange.bind(this);
            this.state = {
                data: selectData(DataSource,props)
            }
        }

        componentDidMount() {
            // ...负责订阅相关的操作...
            DataSource.addChangeListener(this.handleChange);
        }

        componentWillUnmount() {
            DataSource.removeChangeListener(this.handleChange);
        }

        handleChange() {
            this.setState({
              data: selectData(DataSource, this.props)
            });
        }

        render() {
            return <WrappedComponent data={this.state.data} {...this.props} />
        }
    }
}

const CommentListWithSubscription = withSubscription(
    CommentList,
    (DataSource) => DataSource.getComments()
);

const BlogPostWithSubscription = withSubscription(
    BlogPost,
    (DataSource, props) => DataSource.getBlogPost(props.id)
);


//export default CommentListWithSubscription


function Hoc() {
  return (
    <div>
      <CommentListWithSubscription />
      <BlogPostWithSubscription id={1}/>
    </div>
  )
}

export default Hoc;





